package net.lateeye.search.thesissearch.acm;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.StringTokenizer;

import javax.swing.text.html.parser.ParserDelegator;

import net.lateeye.search.AbsResultSet;
import net.lateeye.search.SearchResult;
import net.lateeye.search.thesissearch.ThesisSearchResult;
import net.lateeye.search.thesissearch.ThesisSearchResultPageTextProcessor;
import net.lateeye.util.ExpressionHandler;

public class AcmResultpageProcessor extends ThesisSearchResultPageTextProcessor
{

	// TODO 2008may2/130s. Ok as a default value but this should be set from
	// properties file.
	private static String URLPREFIX_ACM = "http://portal.acm.org/";

	private AcmSRParserForSingleResult singleThesisParser = null;
	private int allDocNum = -1;

	public AcmResultpageProcessor()
	{
		super();
		this.singleThesisParser = new AcmSRParserForSingleResult();
	}

	@Override
	protected String createResult(String queryStr, int orderInResults,
			String docUrl, String docTitle, String urlDomain, String summary)
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected String extractDocTitle(String htmlbody_searchResult)
	{
		return this.singleThesisParser.getThesisTitle();
	}

	@Override
	protected String extractDocUrl(String result)
	{
		String findkey = "<a href";
		String prefix_targetString = "=\"";
		String suffix_targetString = " class";
		String str = super.extractSingleString(result, findkey,
				prefix_targetString, suffix_targetString);
		if (str == null) {
			str = "http://";
		}
		str = str.replaceAll("\"", "");
		return str;
	}

	@Override
	protected long extractEstimatedSize(String htmlbody_searchResult)
	{
		return this.allDocNum;
	}

	@Override
	protected LinkedList<String> extractResults(String htmlbody_searchResult)
	{
		System.out.println("Debug: " + htmlbody_searchResult);
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new ByteArrayInputStream(htmlbody_searchResult.getBytes())));
		AcmHtmlParser parser = new AcmHtmlParser();
		ParserDelegator pd = new ParserDelegator();
		try {
			pd.parse(br, parser, true);
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		this.allDocNum = parser.getAllDocNum();

		LinkedList<String> results = new LinkedList<String>();
		LinkedList<HashMap<String, Integer>> beginAndEndPositions = parser
				.getEachResultStartPositions();
		for (int i = 0; i < beginAndEndPositions.size(); i++) {
			HashMap<String, Integer> poss = beginAndEndPositions.get(i);
			String r = htmlbody_searchResult.substring(poss
					.get(AcmHtmlParser.KEY_BEGINPOS), poss
					.get(AcmHtmlParser.KEY_ENDPOS));
			results.add(r);
		}
		return results;
	}

	@Override
	protected String extractSummary(String result)
	{
		// String findkey = "<p>";
		// String prefix_targetString = "<div class=\"abstract2\">\n\n\n\n\n";
		// String findkey = "<div class=\"abstract2\">\n\n\n\n\n";
		String findkey = "<div class=\"abstract2\">";
		String prefix_targetString = "<p>";
		String suffix_targetString = "</p>";
		String v = super.extractSingleString(result, findkey,
				prefix_targetString, suffix_targetString);
		if (v != null) {
			v = v.replaceAll("[\t ]{1,}", " ");
			// DO: remove unnecessary spaces and tabs
		}
		super.printElement("summary", v);
		return v;
	}

	@Override
	protected AbsResultSet instantiateResultSet()
	{
		return new AcmResultSet();
	}

	@Override
	protected SearchResult extractOtherMetadata(String htm,
			SearchResult result_map)
	{
		ThesisSearchResult thesis = (ThesisSearchResult) result_map;
		// ThesisSearchResult thesis = null;
		if (result_map == null) {
			thesis = new ThesisSearchResult();
		}
		// TODO Q:if "if else", what should be done?/2008may2/130s

		// 1/13/11/130s) Toggled since AcmSRParserForSingleResult needs to be
		// instantiated earlier.
		// this.singleThesisParser = new AcmSRParserForSingleResult();

		BufferedReader br = new BufferedReader(new InputStreamReader(
				new ByteArrayInputStream(htm.getBytes())));
		ParserDelegator pd = new ParserDelegator();
		try {
			pd.parse(br, this.singleThesisParser, true);
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		// DO: set values from HtmlParser
		thesis.setAuthors(this.singleThesisParser.getAuthors());
		thesis.setPublishedyear(this.singleThesisParser.getYearHeld());
		thesis.setFulltextUrl(URLPREFIX_ACM
				+ this.singleThesisParser.getUrl_detailedpage());

		// DO: set values from this' method.
		thesis.setCitationCount(this.extractCitationCount(htm));
		thesis.setKeywords(this.extractKeywords(htm));
		thesis.setPublisher(this.extractPublisher(htm));
		thesis.setPostedConference(this.extractPostedConf(htm));

		return thesis;
	}

	private String extractPostedConf(String htm)
	{
		String findkey = "<div class=\"addinfo\">";
		String prefix_targetString = "<strong>";
		String suffix_targetString = "</font>";
		String v = super.extractSingleString(htm, findkey, prefix_targetString,
				suffix_targetString);
		v = ExpressionHandler.removeHtmlTagsSimply(v);
		if (v != null) {
			// DO: remove unnecessary spaces and tabs
			v = v.replaceAll("[\t ]{1,}", " ");
		}
		super.printElement("postedConf", v);
		return v;
	}

	protected String extractPublisher(String result)
	{
		String findkey = "Publisher:</strong>";
		String prefix_targetString = "&nbsp;";
		String suffix_targetString = "</td>";
		return super.extractSingleString(result, findkey, prefix_targetString,
				suffix_targetString);
	}

	/**
	 * @return If no keywords found, return null.
	 */
	protected LinkedList<String> extractKeywords(String result)
	{
		String findkey = "<b>Keywords";
		String prefix_targetString = "</b>:";
		// String suffix_targetString = "<br>&nbsp;"; //1/13/11 Found obsolete
		String suffix_targetString = "</div>"; // From 1/13/2011

		// Do) Extract the entire string from keyword section.
		String extracted = null;
		try {
			extracted = super.extractSingleString(result, findkey,
					prefix_targetString, suffix_targetString);
		} catch (IndexOutOfBoundsException e) {
			// Do) If no keyword found, return null.
			return null;
		}
		super.printElement("keywords", extracted);

		// Do) Tokenize keywords and put each into a list.
		StringTokenizer st = new StringTokenizer(extracted, ",");
		LinkedList<String> kws = new LinkedList<String>();
		while (st.hasMoreTokens()) {
			kws.add(st.nextToken());
		}
		return kws;
	}

	protected int extractCitationCount(String result)
	{
		// String findkey = "Count:";
		String findkey = "Citation ";
		// String prefix_targetString = "Citation ";
		String prefix_targetString = "Count:";
		String suffix_targetString = "</td>";
		String v = super.extractSingleString(result, findkey,
				prefix_targetString, suffix_targetString);
		v = ExpressionHandler.removeSpaceAttheBeginning(v);
		return Integer.parseInt(v);
	}

	@Override
	/*
	 * 
	 * @return an instance just generated of ThesisSearchResult. Since ACM
	 * search doesn't require a special search result characteristics, here just
	 * use it.
	 */
	protected SearchResult instantiateSingleSearchResult()
	{
		return new ThesisSearchResult();
	}
}